window.onload = function() {
  initDb();
  
  //deleteDb(); // for debugging

  showFeeds();
  
  loadFeeds();
}

var oldfeed_div;

function showFeeds() {
  var feeds = selectFeeds();
  
  var feedContent = "";
  
  for (var x = 0; x < feeds.length; x++) {
    var feed = feeds[x];
    feedContent += '<div class="unselectedFeed" onclick="getFeed(this, ' + feed.id + ')">' + feed.title + '</div>';
  }
  
  document.getElementById('feedListContainer').innerHTML = feedContent;
}
  
function loadFeeds() {
  showLoading();
      
  try {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "sample.opml");
    xhr.onreadystatechange = function() {
      if ( (xhr.readyState == 4) ) { //&& (xhr.status == 200) ) {
        var opml = xhr.responseXML;

        if (opml == null) {
          loadFeedsHardCoded();
          return;
        }
        var outlines = opml.getElementsByTagName("outline");
        var feedContent = "";
          
        for (var i = 0; i < outlines.length; i++) {
          var title = outlines[i].getAttribute("text");
          var feedUrl = outlines[i].getAttribute("xmlUrl");
          if (title && feedUrl) {
            addFeed(title, feedUrl, '');
          }
        }
        showNothing();
      }
    }
    xhr.send(null);
  } catch (e) { // offline
    alert('should glog that I am offline');
  }
}

function loadFeedsHardCoded() {
  showLoading();
  
  var feeds = [
      { title: 'techno.blog',
        url: 'http://almaer.com/blog/index.xml' },
      { title: 'Google Code',
        url: 'http://code.google.com/feeds/updates.xml' },
      { title: 'Google Code Featured Projects',
        url: 'http://code.google.com/feeds/featured.xml' },
      { title: 'Ajaxian',
        url: 'http://ajaxian.com/feed' },
      { title: 'Ajax Cookbook',
        url: 'http://ajaxcookbook.org/feed/' },
  ];
  
  for (var x = 0; x < feeds.length; x++) {
    addFeed(feeds[x].title, feeds[x].url, '');
  }
  
  showNothing();
  
  showFeeds();
}

function getFeed(feed_div, feed_id) {
  showLoading();
  
  var feed = selectFeed(feed_id);

  if (oldfeed_div != null) oldfeed_div.className = "unselectedFeed";
  oldfeed_div = feed_div;

  feed_div.className = "selectedFeed";
  
  var posts = selectPosts(feed_id);
  
  if (posts.length < 1) {
    loadPosts(feed, feed_div);
    setTimeout(function() {
      getFeed(feed_div, feed_id);
    }, 100);
    return;
  } else {
    setTimeout(function() {
      loadPostsFromService(feed);
    }, 100000);
  }
  
  showPosts(feed, posts);
}

function showPosts(feed, posts) {
  var html = "";                

  html += '<div class="titlebar">';
  html += '<div class="title"><a href="' + feed.url + '">' + feed.title + '</a></div>';
  html += '<div class="description">' + feed.description + '</div>';
  html += '</div><div class="entries">';

  for (i = 0; i < posts.length; i++) {
    var entry = posts[i];
    
    html += '<div class="entryTitle"><a href="' + entry.url + '">' + entry.title + '</a></div>';
    html += '<div class="entryText">' + entry.content + '</div>';
  }

  html += "</div>";
  
  document.getElementById("feedContent").innerHTML = html;
}

function loadPosts(feed, feed_div) {
  loadPostsFromService(feed);

  // Go ahead and load the posts again in a little bit
  setTimeout(function() {
    loadPostsFromService(feed);
  }, 100000);
}

function loadPostsFromService(feed) {
  new google.feeds.Feed(feed.url).load(function(result) {
    if (!result.error) {
      for (i = 0; i < result.feed.entries.length; i++) {
        var entry = result.feed.entries[i];
          
        addPost(feed.id, entry.title, entry.link, entry.content);
      }
    }
  });
}  

  
// Gears stuff
var db;

function initDb() {
  if (!window.google || !google.gears) {
    return;
  }

  db = getDb();
  
  run('create table if not exists feeds (' +
             'id integer not null primary key autoincrement,' +
             'title varchar(255),' +
             'url varchar(255),' +
             'description text)');
             
  run('create table if not exists posts (' +
             'id integer not null primary key autoincrement,' +
             'feed_id integer,' +
             'title varchar(255),' +
             'url varchar(255),' +
             'content text)');
}
  
function getDb() {
  try {
    var theDb = google.gears.factory.create('beta.database', '1.0');
    theDb.open('rssbling');
    return theDb;
  } catch (e) {
    alert('Could not create the rssbling database: ' + e.message);
  }
}
  
function addFeed(title, url, description) {
  var rslt = executeToObjects('select id from feeds where title = ? and url = ?', [title, url])[0];
  if (rslt) { return; }
  run('insert into feeds (title, url, description) values (?, ?, ?)', [title, url, description]);
}

function addPost(feed_id, title, url, content) {
  var rslt = executeToObjects('select id from posts where feed_id = ? and url = ?', [feed_id, url])[0];
  if (rslt) { return; }
  run('insert into posts (feed_id, title, url, content) values (?, ?, ?, ?)', [feed_id, title, url, content]);
}

function selectFeed(id) {
  return executeToObjects("select * from feeds where id = ?", [id])[0];
}
  
function selectFeeds() {
  return executeToObjects("select * from feeds", null);
}

function selectPosts(feed_id) {
  return executeToObjects("select * from posts where feed_id = ?", [feed_id]);
}

function executeToObjects(sql, args) {
  var rs = db.execute(sql, args);
  try {
    var rv = [];
    if (rs && rs.isValidRow()) {
      var cols = rs.fieldCount();
      var colNames = [];
      for (var i = 0; i < cols; i++) {
	      colNames.push(rs.fieldName(i));
      }

      while (rs.isValidRow()) {
	      var h = {};
	      for (i = 0; i < cols; i++) {
	        h[colNames[i]] = rs.field(i);
	      }
	      rv.push(h);
	      rs.next();
      }
    }
  } catch (e) {
    throw e;
  } finally {
    rs.close();
    return rv;
  }
}

function run(sql, args) {
  try {
    db.execute(sql, args);
  } catch (e) {
    alert("Trying to run: " + sql + "producing error: " + e.message);
  }
}

function deleteDb() { // for debugging
  run("delete from feeds");
  run("delete from posts");
}

// -- show info in the main pane

function showError() {
  var html = "";
  html += '<table width="100%" height="100%">';
  html += '<tr><td valign="middle" align="center" class="error">';
  html += 'An error occured';
  html += '</td></tr></table>';
  showSomething(html);
}

function showLoading() {
  var html = "";
  html += '<table width="100%" height="100%">';
  html += '<tr><td valign="middle" align="center" class="status">';
  html += 'Loading feeds...';
  html += '</td></tr></table>';
  showSomething(html);
}

function showNothing() {
  var html = "";
  html += '<table width="100%" height="100%">';
  html += '<tr><td valign="middle" align="center" class="status">';
  html += 'Click on a feed in the left sidebar...';
  html += '</td></tr></table>';
  showSomething(html);
}

function showSomething(html) {
  document.getElementById("feedContent").innerHTML = html;
}
